#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, os, math, logging
from datetime import datetime
from functools import wraps

from google.appengine.api import users

from django.http import *
from appengine_utilities.sessions import Session
from appengine_utilities.flash import Flash
from google.appengine.api import memcache

from xmsmodels import *
from ccchart import googlechart

sys_loginurl=users.create_login_url("/")
sys_logouturl=users.create_logout_url("/")


loginurl="/login"
logouturl="/logout"

class enum(object):
    def __init__(self, dicts):
    	for key in dicts.keys():
    		setattr(self,key,dicts[key])

            
def requires_login(method):
    @wraps(method)
    def wrapper(self, *args, **kwargs):
        if not users.get_current_user():
            return HttpResponseRedirect(loginurl)
        else:
            return method(self, *args, **kwargs)
    return wrapper


def check_current_user_and_group_admin(method):
    @wraps(method)
    def wrapper(self, *args, **kwargs):
        session = Session()
        curUser = session.get('CurrentUser',None)
        if not curUser or curUser.key() != XMSUser.GetXMSUserByUser(users.get_current_user()).key():
            return HttpResponseRedirect(loginurl)
        else:
            curGroup = XMSGroup.GetActivedGroupByName(session.get('CurrentGroup',None))
            if not curGroup or not curUser.IsAdminOfGroup(curGroup):
                flash = Flash()
                flash.msg = u"You are not the Admin of Group %s" %(curGroup.GroupName)
                return HttpResponseRedirect("/")
            return method(self, *args, **kwargs)
    
    return wrapper

def check_current_user_and_group(method):
    @wraps(method)
    def wrapper(self, *args, **kwargs):
        session = Session()
        curUser = session.get('CurrentUser',None)
        if not curUser or curUser.key() != XMSUser.GetXMSUserByUser(users.get_current_user()).key():
            return HttpResponseRedirect(loginurl)
        else:
            curGroup = XMSGroup.GetActivedGroupByName(session.get('CurrentGroup',None))
            if not curGroup or not curUser.IsUserOfGroup(curGroup):
                flash = Flash()
                flash.msg = u"You are not in the Group %s" %(curGroup.GroupName)
                return HttpResponseRedirect("/")
            return method(self, *args, **kwargs)
    
    return wrapper

def check_current_user(method):
    @wraps(method)
    def wrapper(self, *args, **kwargs):
        session = Session()
        curuser = session.get('CurrentUser',None)
        if not curuser or curuser.key() != XMSUser.GetXMSUserByUser(users.get_current_user()).key():
            return HttpResponseRedirect(loginurl)
        else:
            return method(self, *args, **kwargs)
    return wrapper

def requires_site_admin(method):
    @wraps(method)
    def wrapper(self, *args, **kwargs):
        if not users.is_current_user_admin():
            return HttpResponseRedirect(logouturl)
        else:
            return method(self, *args, **kwargs)
    return wrapper

def format_date(dt):
    return dt.strftime('%a, %d %b %Y %H:%M:%S GMT')

def cache(method):
    @wraps(method)
    def _wrapper(*args, **kwargs):
        key = ""
        resp = memcache.get(key)
        if resp is not None:
            return resp
        else:
            resp = method(*args, **kwargs)
            if resp.status_code == 200:
                if not memcache.set(key, resp, 60):
                    logging.error("Memcache set failed.")
            return resp
    return _wrapper
    
class Pager(object):

    def __init__(self, model=None,query=None, items_per_page=8, pages_follow = 5, pages_skip = 10):
        if model:
            self.query = model.all()
        elif query:
            self.query=query

        self.items_per_page = items_per_page
        self.pages_follow = pages_follow
        self.pages_skip = pages_skip

    def fetch(self, p):
        max_offset = self.query.count()
        n = max_offset / self.items_per_page
        if max_offset % self.items_per_page != 0:
            n += 1

        if p < 0 or p > n:
            p = 1
        offset = (p - 1) * self.items_per_page
        results = self.query.fetch(self.items_per_page, offset)



        links = {'count':max_offset,'page_index':p, 
                 'page_count': int(math.ceil(((float)(max_offset))/self.items_per_page)),
                 'prev': p - 1, 'next': p + 1, 'last': n,
                 'follow':range(p+1,n+1),
                 'lead':[],}
        if p > self.pages_skip:
            links['lead'].append(p-self.pages_skip)
        start = 1
        if p-self.pages_follow > start:
            start = p-self.pages_follow
        links['lead'] += range(start,p)
        
        
        if len(links['follow']) > self.pages_follow:
            links['follow'] = links['follow'][:self.pages_follow]
        if links['page_count'] - p > self.pages_skip:
            links['follow'].append(p+self.pages_skip)
        
        if links['next'] > n:
            links['next'] = 0

        return (results, links)
    
class XMSReport():
    
    @staticmethod
    def GetData(curGroup,reporttype, count):
        data = []
        legend = []
        if reporttype not in ['date','month','user']:
            raise TypeError(r"Reprot type must in ['date','month','user']")
        
        temp = {}
        if reporttype in ['date','month']:
            payouts = curGroup.GetPayoutsByDate()
            for payout in payouts:
                date = payout.Datetime.date()
                money = float(payout.Money)
                if reporttype == 'month':
                    date = datetime(date.year, date.month, 1).date()
                if temp.has_key(date):
                    temp[date] += money
                else:
                    temp[date] = money
                if len(temp) >= count:
                    break
            labels = temp.keys()
            labels.sort()
            for label in labels:
                if reporttype == 'month':
                    legend.append("%s.%s" %(label.year,label.month))
                else:
                    legend.append(label)
                data.append(temp[label])
                
        elif reporttype == 'user':       #type = 'user'
            payouts = curGroup.GetPayoutsByUser()
            for payout in payouts:
                user = payout.User.NickName
                money = float(payout.Money)
                if temp.has_key(user):
                    temp[user] += money
                else:
                    temp[user] = money
            li = []
            for k in temp.keys():
                money = temp[k]
                li.append((money,k))
            li.sort(reverse=True)
            for i in range(count):
                if i < len(li):
                    data.append(li[i][0]) 
                    legend.append(li[i][1])              
        
        return (data,legend)
    
    @staticmethod
    def GetReportPath(charttype,reporttype,count,title="",size = (600,450)):
        #try:
            imagepath = "/static/images/report.jpg"
            session = Session()
            curGroup = XMSGroup.GetActivedGroupByName(session.get('CurrentGroup',None))
                
            chchekey = "%s-%s-%d" %(curGroup.GroupName,reporttype,count)
            cache = memcache.get(chchekey)
            if cache is not None:
                (data,legend) = cache
            else:
                (data,legend) = XMSReport.GetData(curGroup,reporttype,count)
                if data:
                    memcache.set(chchekey,(data,legend),60)
            
            if not data:
                return imagepath
            data = [float("%.2f"%d) for d in data]
            if charttype == 'bar':
                imagepath = googlechart.singleBarChart(legend,data,size,\
                                           showlegend='n',tickcount=5,\
                                           title=title)
            elif charttype == 'line':
                imagepath = googlechart.simpleLineChart(legend,data,size,\
                                           showlegend='n',tickcount=5,\
                                           title=title)
                pass
            elif charttype == 'pie':
                imagepath = googlechart.pieChart(legend,data,size,\
                                                 showlegend='n',tickcount=5,\
                                                 title=title)
            return imagepath
        #except:
            #return "/static/images/report.jpg"
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        